package org.example3;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 *  将MyClass.src拷贝到target目录的org/example3中,并改名为MyClass.java
 *
 *  编译源代码MyClass.java,并运行编译后的字节码
 */
public class AppCompiler {
    public static void main(String[] args) throws Exception{
        //第一步:将MyClass.src复制到target目录的org/example3目录中
        String filePath = System.getProperty("user.dir") +"/jdkProxy/src/main/java/"+
                AppCompiler.class.getPackage().getName().replace(".","/") + "/MyClass.src";
        String dest = copyFile2Dest(filePath);

        //第二步,编译复制后的目标源文件
        Object o = compileJavaSrc(dest);

        //第三步,通过反射调用对象的方法
        System.out.println(o);
        if (o.getClass().getName().equals(AppCompiler.class.getPackage().getName()+".MyClass")) {
            System.out.println("进入if判断了");
            Method show = o.getClass().getDeclaredMethod("show");
            show.invoke(o);
        }

    }

    public static String copyFile2Dest(String src) throws Exception{
        String destPath = System.getProperty("user.dir") +"/jdkProxy/target/classes/"+AppCompiler.class.getPackage().getName().replace(".","/")  + "/MyClass.java";
        FileInputStream fileInputStream = new FileInputStream(src);
        FileOutputStream fileOutputStream = new FileOutputStream(destPath);

        byte[] bytes = new byte[1024];
        int len;

        while ((len =fileInputStream.read(bytes)) != -1) {
            fileOutputStream.write(bytes, 0, len);
        }

        fileOutputStream.close();
        fileInputStream.close();

        return destPath;
    }


    public static Object compileJavaSrc(String filePath) throws IOException, ClassNotFoundException,
            NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //3.把生成的.java文件编译成.class文件
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager manage = compiler.getStandardFileManager(null, null, null);
        Iterable iterable = manage.getJavaFileObjects(new File(filePath));

        JavaCompiler.CompilationTask task = compiler.getTask(null, manage, null, null, null, iterable);
        task.call();
        manage.close();

        //4.编译生成的.class文件加载到JVM中
        Class proxyClass =new MyClassLoader().findClass(filePath.replace(".java",".class"));
        Constructor c = proxyClass.getConstructor();
//            f.delete();  // 删除生成的java源代码

        //5.返回字节码重组以后的新的代理对象
        return c.newInstance();
    }
}
